﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using FastColoredTextBoxNS;
namespace VASMide
{
    
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            Form1.languages.Add(new VASM());
            Form1.languages.Add(new Diamond());
            CheckForIllegalCrossThreadCalls = false;
            start s = new start();
            s.MdiParent = this;
            s.Show();
            s.Size = s.MaximumSize;
            s.WindowState = FormWindowState.Maximized;
            /*
            startForm sf = new startForm();
            sf.TopMost = true;
            sf.Show();
             */
           
        }
        private void fastColoredTextBox1_Load(object sender, EventArgs e)
        {

        }
        public static List<Language> languages = new List<Language>();
        string output = "";
        void build()
        {
            string asmc = "";
            if (File.Exists(fb.SelectedFile))
            {
                StreamWriter sw = new StreamWriter(fb.SelectedFile);
                sw.Write(Form1.c.fastColoredTextBox1.Text);
                sw.Close();
            }
            foreach (string f in Project.SourceFiles)
            {
                asmc += File.ReadAllText(f) + "\n";
            }


            toolStripStatusLabel1.Text = "Build Started";
            foreach (Language s in languages)
            {
                if (s.name == Project.TargetLanguage)
                {
                    try
                    {
                        s.Imports = Project.References;
                        s.build(asmc);
                        frm2.textBox1.Text = s.outPut;
                        output = s.outPut;
                        toolStripStatusLabel1.Text = "Build Succeceded!";
                    }
                    catch (Exception msg)
                    {
                        toolStripStatusLabel1.Text = "Build Failed!";
                        MessageBox.Show(msg.ToString());
                        
                    }
                }
            }
           
        }
        private void buildToolStripMenuItem_Click(object sender, EventArgs e)
        {
            build();
        }
        private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            build();
            File.Copy(Project.Path + @"\bin\app.gex", saveFileDialog1.FileName, true);
            
           
        }

        private void exportGEXToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.ShowDialog();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog2.ShowDialog();
        }

        private void saveFileDialog2_FileOk(object sender, CancelEventArgs e)
        {
            if (!e.Cancel)
            {
                StreamWriter sw = new StreamWriter(saveFileDialog2.FileName);
                sw.WriteLine(c.fastColoredTextBox1.Text);
                sw.Close();
            }
        }
        public static codeEditor c;

        private void codeEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            c = new codeEditor();
            c.MdiParent = this;
            c.Dock = DockStyle.Fill;
            c.Show();
        }

        private void fileBrowserToolStripMenuItem_Click(object sender, EventArgs e)
        {
            filebrowser fb = new filebrowser();
            fb.MdiParent = this;
            fb.Dock = DockStyle.Left;
            fb.Show();
        }
        public static viperv3.ViperVirtualMachine vm = null;
        private void buildAndRunToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BuildAndRun();
            
        }
        void BuildAndRun()
        {
            build();
            Viper.Assembly asm = new Viper.Assembly();
            asm.LoadGEX(Project.Path + @"\bin\app.gex");
            
            asmb = asm;
            t = new Thread(r);
            t.Start();
        }
    
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern bool AllocConsole(); 
        Thread t;
        public static Form2 frm2;
        Viper.Assembly asmb;
        
        void r()
        {
            vm = new viperv3.ViperVirtualMachine();
            vm.Output = "";
            vm.ExceptInput = false;
            vm.redirectOutput = true;
            vm.Refresh += frm2.redraw;
            vm.nextOpcode += vd.refresh;
            
            vm.Debug = true;
            vm.ConsoleMode = true;
            vm.Debug = true;
            vm.Run(asmb);
            vm = null;
            
            
        }
        filebrowser fb;


        public void loadItems()
        {
            timer1.Start();
            Point fbloc;
            Point celoc;
            Point oploc;
            Size fbsize;
            Size cesize;
            Size opsize;
            fb = new filebrowser();
            fb.MdiParent = this;
            fb.Dock = DockStyle.Left;
            fb.Show();
            fbloc = fb.Location;
            fbsize = fb.Size;
            frm2 = new Form2();
            
            frm2.MdiParent = this;
            frm2.Dock = DockStyle.Bottom;
            frm2.Show();
            oploc = frm2.Location;
            opsize = frm2.Size;
            c = new codeEditor();
            c.MdiParent = this;
            c.Dock = DockStyle.Fill;

            c.WindowState = FormWindowState.Normal;
            c.Show();
            celoc = c.Location;
            c.WindowState = FormWindowState.Normal;
            cesize = c.Size;
            foreach (Language l in languages)
            {
                if (l.name == Project.TargetLanguage)
                {
                    c.keywords = l.keyWords; 
                    c.indentWords = l.indentKeywords;
                    c.unindentWords = l.unindentKeywords;
                }
            }
            c.fastColoredTextBox1.Text = System.IO.File.ReadAllText(Project.SourceFiles[0]);
      
        }
        private void outputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frm2 = new Form2();
            frm2.MdiParent = this;
            frm2.Dock = DockStyle.Bottom;

            frm2.Show();
        }

        private void addClassToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ClassWizard cw = new ClassWizard();
            cw.Show();
        }

        private void breakToolStripMenuItem_Click(object sender, EventArgs e)
        {
            t.Abort();
            
        }
vmdebug vd = new vmdebug();
          
        private void vIPERVMDebugWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            vd.MdiParent = this;
            vd.TopMost = true;
            vd.BringToFront();
            vd.Show();
        }
        bool con = false;
         
        private void runInConsoleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            build();
            System.Diagnostics.Process.Start("vrt.exe", "\"" + Project.Path + @"\bin\app.gex" + "\"");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (t != null)
            {
                if (t.ThreadState == ThreadState.Suspended)
                {
                    toolStripStatusLabel1.Text = "Paused";
                }
                else if (t.IsAlive)
                {
                    c.fastColoredTextBox1.ReadOnly = true;
                    toolStripStatusLabel1.Text = "Running";
                }
                
                else
                {
                    c.fastColoredTextBox1.ReadOnly = false;
                    toolStripStatusLabel1.Text = "Ready";
                }
            }
        
        
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            BuildAndRun();
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            if(t != null)
                t.Abort();
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            options o = new options();
            o.TopMost = true;
            o.Show();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F5)
            {
                if (!t.IsAlive)
                {
                    BuildAndRun();
                }
            }
        
        }

        private void compileToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            if (t.IsAlive)
            {
                t.Suspend();
                toolStripStatusLabel1.Text = "Paused";
            }
        }

        private void helpToolStripButton_Click(object sender, EventArgs e)
        {
            HelpBrowser hb = new HelpBrowser();
            hb.Show();
        }

        private void addReferenceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            if (File.Exists(openFileDialog1.FileName))
            {
                File.Copy(openFileDialog1.FileName, Project.Path + @"\" + Path.GetFileName(openFileDialog1.FileName),true);
                Project.References.Add(openFileDialog1.FileName);
                fb.refreshItems();
            }
        }

        private void cutToolStripButton_Click(object sender, EventArgs e)
        {
            c.fastColoredTextBox1.Cut();
        }

        private void copyToolStripButton_Click(object sender, EventArgs e)
        {
            c.fastColoredTextBox1.Copy();
        }

        private void pasteToolStripButton_Click(object sender, EventArgs e)
        {
            c.fastColoredTextBox1.Paste();
        }

        private void newToolStripButton_Click(object sender, EventArgs e)
        {
            startForm sf = new startForm();
            sf.TopMost = true;
            sf.Show();
        }

        private void openToolStripButton_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
            folderBrowserDialog1.SelectedPath = Application.StartupPath;
            folderBrowserDialog1.ShowDialog();
            startForm.loadProject(folderBrowserDialog1.SelectedPath); 
        }

        private void viewCompilerOutputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (File.Exists(fb.SelectedFile))
            {
                StreamWriter sw = new StreamWriter(fb.SelectedFile);
                sw.Write(Form1.c.fastColoredTextBox1.Text);
                sw.Close();
            }
            fb.SelectedFile = "//COMPILEROUTPUT";
            c.fastColoredTextBox1.Text = output;
        }
    }
    public class Project
    {
        public static string TargetLanguage;
        public static string Path = "";
        public static List<string> SourceFiles = new List<string>();
        public static List<string> Headers = new List<string>();
        public static List<string> References = new List<string>();
       
    }
}
